Skip to content

fix(#711): enforce sender ownership on cancel endpoint and fix pre-existing blockers - #909

Open
Danielkallala wants to merge 1 commit into
ritik4ever:mainfrom
Danielkallala:fix/711-cancel-sender-validation
Open

fix(#711): enforce sender ownership on cancel endpoint and fix pre-existing blockers#909
Danielkallala wants to merge 1 commit into
ritik4ever:mainfrom
Danielkallala:fix/711-cancel-sender-validation

Conversation

@Danielkallala

Copy link
Copy Markdown

Overview

This PR fixes issue #711 by ensuring the POST /api/streams/:id/cancel endpoint properly validates sender ownership. The endpoint already had authMiddleware and a sender ownership check on main, but three pre-existing bugs prevented it from actually working, causing 500 errors.

Related Issue

Closes #711

Changes

🔧 Fix malformed TransactionBuilder in streamStore.ts

  • Removed merge conflict artifact that created invalid syntax in the Soroban path
  • The duplicate new TransactionBuilder(...) call caused a syntax error preventing compilation

📦 Add missing syncFtsIndex export to db.ts

  • streamStore.ts imported syncFtsIndex from db.ts but it was never defined
  • Added as a no-op since the FTS virtual table is not yet created

🗄️ Add missing cliff_seconds column via addColumnIfMissing in initDb()

  • upsertStream() references cliff_seconds column but no migration existed for it
  • Used the addColumnIfMissing pattern for backwards-compatible schema patching

🧪 Initialize cache in test setup files

  • auth.test.ts and streamStore.cancel.integration.test.ts now call initCache() before tests
  • Required because cancelStream() calls invalidateCache() which throws if cache is not initialized

Verification Results

cd backend && npx vitest run src/auth.test.ts src/services/streamStore.cancel.integration.test.ts src/services/migrations.test.ts

✅ 17/17 auth tests passed

  • ✅ recipient cannot cancel the stream → 403
  • ✅ third party cannot cancel the stream → 403
  • ✅ sender can cancel the stream → 200

✅ 7/7 cancel integration tests passed

  • ✅ Cancel active stream → 200 with canceledAt set
  • ✅ Cancel completed stream → 200
  • ✅ Cancel not found → 404
  • ✅ Non-sender cancel → 403
  • ✅ No token → 401
  • ✅ Idempotent cancel → 200
  • ✅ Event history verification

✅ 4/4 migration tests passed

Acceptance Criteria

Criteria Status
Cancel endpoint verifies JWT/signature matches stream sender ✅ authMiddleware + sender ownership check
Non-sender cancel returns 403 ✅ Tested for recipient, third party, and unauthenticated
Test added for unauthorized cancel ✅ auth.test.ts covers all unauthorized scenarios

Files Changed

File Change
backend/src/services/streamStore.ts Removed malformed TransactionBuilder code
backend/src/services/db.ts Added syncFtsIndex, addColumnIfMissing, and cliff_seconds column patch
backend/src/auth.test.ts Added initCache() call in test setup
backend/src/services/streamStore.cancel.integration.test.ts Added initCache() call in test setup

🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com

…fix pre-existing blockers

The cancel endpoint already had authMiddleware and a sender ownership check
on main, but three pre-existing issues prevented the endpoint from working:

- Fix malformed TransactionBuilder in streamStore.ts (merge conflict artifact)
- Add missing syncFtsIndex export to db.ts (imported but never defined)
- Add missing cliff_seconds column via addColumnIfMissing in initDb()
- Initialize cache in auth.test.ts and cancel integration test

All 28 related tests now pass (auth, cancel, migrations).

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@vercel

vercel Bot commented Aug 29, 2026

Copy link
Copy Markdown

@Danielkallala is attempting to deploy a commit to the ritik4ever's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Aug 29, 2026

Copy link
Copy Markdown

@Danielkallala Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c47bfc0f-a3ae-4953-bc75-6298565ed919


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] POST /api/streams/:id/cancel does not validate sender ownership

1 participant